{*******************************************************************************
* The contents of this file are used with permission, subject to the Mozilla   *
* Public License Version 1.1 (the "License"); you may not use this file except *
* in compliance with the License. You may obtain a copy of the License at      *
* http://www.mozilla.org/MPL/                                                  *
*                                                                              *
* Software distributed under the License is distributed on an "AS IS" basis,   *
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for *
* the specific language governing rights and limitations under the License.    *
*                                                                              *
* The Original Code is distributed as part of the "mediate" product and is     *
* Copyright (C) @home media limited. All Rights Reserved.                      *
*                                                                              *
* Email: support@athomemedia.co.uk                                             *
* Web:   http://www.athomemedia.co.uk                                          *
*******************************************************************************}

unit CameraManager;

interface

uses CameraSchema, Mediate_TLB, DBSchema, GPSParser, GPSConsts;

const
  LATITUDE_DIFF = 0.2; // These two diff values will provide a "box" around our current position
  LONGITUDE_DIFF = 0.2;// with which we can search camera proximity, we will need to tweak these values
                      // when we start testing the camera warnings

type
  TAHMUnits = (umMiles, umKilometers, umNauticalMiles);

  TAHMCameraManager = class
  private
    FMediate: IMediateServer;
    FSchema: TAHMCameraSchema;
    FUnits: TAHMUnits;
  protected
    procedure LogMessage(Level: LoggingLevel; LogMessage: String);
  public
    property DistanceUnits: TAHMUnits read FUnits;
    constructor Create(Server: IMediateServer);
    destructor Destroy; override;
    procedure SpeedCameraWarningCheck(Parser: TAHMGPSParser);
    property Schema: TAHMCameraSchema read FSchema;
  end;

implementation

uses Math;

constructor TAHMCameraManager.Create(Server: IMediateServer);
var
  ConfigDir: WideString;
begin
  inherited Create;

  // Store server instance & build database filename
  FMediate := Server;
  Server.GetConfigDirectory(ConfigDir);

  FSchema := TAHMCameraSchema.Create;
  FSchema.Filename := ConfigDir + CAMERA_DB_FILENAME;
end;

destructor TAHMCameraManager.Destroy;
begin
  FSchema.Free;

  inherited;
end;

procedure TAHMCameraManager.LogMessage(Level: LoggingLevel; LogMessage: String);
begin
  FMediate.LogMessage(Level, LogMessage);
end;

function Distance(Lat1, Lon1, Lat2, Lon2:Extended; Units: TAHMUnits): Extended;
begin
  // Result in miles
  Result := RadToDeg(Arccos(Sin(DegToRad(Lat1)) * Sin(DegToRad(Lat2))
            + Cos(DegToRad(Lat1)) * Cos(DegToRad(Lat2)) * Cos(DegToRad(Lon1 - Lon2))))*60*1.1515;

  if Units = umKilometers then
    //Result in Kilometeres
    Result := Result * 1.609344
  else if Units = umNauticalMiles then
    //Result in Nautical Miles
    Result := result * 0.8684;
end;

procedure TAHMCameraManager.SpeedCameraWarningCheck(Parser: TAHMGPSParser);
var
  minLat: Double;
  minLong: Double;
  maxLat: Double;
  maxLong: Double;
  cameraList: TAHMDBResult;
begin
  //TODO SA Add a check to see that we actually have speed camera warning enabled
  //This will be done by checking some persisted value
  if (true) then
    begin
     minLat := Parser.Lattitude - LATITUDE_DIFF;
     minLong := Parser.Longitude - LONGITUDE_DIFF;
     maxLat := Parser.Lattitude + LATITUDE_DIFF;
     maxLong := Parser.Longitude + LONGITUDE_DIFF;

     cameraList := FSchema.ListCameras('UK',minLat,minLong,maxLat,maxLong);
     if Assigned(cameraList) then
     begin
         if cameraList.RowCount > 0 then
         //TODO Need to get the distance to nearest camera
         FMediate.SetMetaData(META_GPS_WARNING, 'CameraAlert')
       else
         FMediate.ClearMetaData(META_GPS_WARNING);
     end
     else
       LogMessage(llDebug, 'Failed to retrieve list of cameras from database');
    end
  else
    FMediate.ClearMetaData(META_GPS_WARNING);
end;

end.
